home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / TEXTURE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.9 KB  |  257 lines

  1. #include <stdio.h>
  2. #include <stdlib.h> 
  3. #include <string.h>
  4.  
  5. void
  6. bwtorgba(unsigned char *b,unsigned char *l,int n) {
  7.     while(n--) {
  8.     l[0] = *b;
  9.     l[1] = *b;
  10.     l[2] = *b;
  11.     l[3] = 0xff;
  12.     l += 4; b++;
  13.     }
  14. }
  15.  
  16. void
  17. latorgba(unsigned char *b, unsigned char *a,unsigned char *l,int n) {
  18.     while(n--) {
  19.     l[0] = *b;
  20.     l[1] = *b;
  21.     l[2] = *b;
  22.     l[3] = *a;
  23.     l += 4; b++; a++;
  24.     }
  25. }
  26.  
  27. void
  28. rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
  29.     while(n--) {
  30.     l[0] = r[0];
  31.     l[1] = g[0];
  32.     l[2] = b[0];
  33.     l[3] = 0xff;
  34.     l += 4; r++; g++; b++;
  35.     }
  36. }
  37.  
  38. void
  39. rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
  40.     while(n--) {
  41.     l[0] = r[0];
  42.     l[1] = g[0];
  43.     l[2] = b[0];
  44.     l[3] = a[0];
  45.         l += 4; r++; g++; b++; a++;
  46.     }
  47. }
  48.  
  49. typedef struct _ImageRec {
  50.     unsigned short imagic;
  51.     unsigned short type;
  52.     unsigned short dim;
  53.     unsigned short xsize, ysize, zsize;
  54.     unsigned int min, max;
  55.     unsigned int wasteBytes;
  56.     char name[80];
  57.     unsigned long colorMap;
  58.     FILE *file;
  59.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  60.     unsigned long rleEnd;
  61.     unsigned int *rowStart;
  62.     int *rowSize;
  63. } ImageRec;
  64.  
  65. static void
  66. ConvertShort(unsigned short *array, long length) {
  67.     unsigned b1, b2;
  68.     unsigned char *ptr;
  69.  
  70.     ptr = (unsigned char *)array;
  71.     while (length--) {
  72.     b1 = *ptr++;
  73.     b2 = *ptr++;
  74.     *array++ = (b1 << 8) | (b2);
  75.     }
  76. }
  77.  
  78. static void
  79. ConvertLong(unsigned *array, long length) {
  80.     unsigned b1, b2, b3, b4;
  81.     unsigned char *ptr;
  82.  
  83.     ptr = (unsigned char *)array;
  84.     while (length--) {
  85.     b1 = *ptr++;
  86.     b2 = *ptr++;
  87.     b3 = *ptr++;
  88.     b4 = *ptr++;
  89.     *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  90.     }
  91. }
  92.  
  93. static ImageRec *ImageOpen(const char *fileName)
  94. {
  95.     union {
  96.     int testWord;
  97.     char testByte[4];
  98.     } endianTest;
  99.     ImageRec *image;
  100.     int swapFlag;
  101.     int x;
  102.  
  103.     endianTest.testWord = 1;
  104.     if (endianTest.testByte[0] == 1) {
  105.     swapFlag = 1;
  106.     } else {
  107.     swapFlag = 0;
  108.     }
  109.  
  110.     image = (ImageRec *)malloc(sizeof(ImageRec));
  111.     if (image == NULL) {
  112.     fprintf(stderr, "Out of memory!\n");
  113.     exit(1);
  114.     }
  115.     if ((image->file = fopen(fileName, "rb")) == NULL) {
  116.     perror(fileName);
  117.     exit(1);
  118.     }
  119.  
  120.     fread(image, 1, 12, image->file);
  121.  
  122.     if (swapFlag) {
  123.     ConvertShort(&image->imagic, 6);
  124.     }
  125.  
  126.     image->tmp = (unsigned char *)malloc(image->xsize*256);
  127.     image->tmpR = (unsigned char *)malloc(image->xsize*256);
  128.     image->tmpG = (unsigned char *)malloc(image->xsize*256);
  129.     image->tmpB = (unsigned char *)malloc(image->xsize*256);
  130.     if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
  131.     image->tmpB == NULL) {
  132.     fprintf(stderr, "Out of memory!\n");
  133.     exit(1);
  134.     }
  135.  
  136.     if ((image->type & 0xFF00) == 0x0100) {
  137.     x = image->ysize * image->zsize * sizeof(unsigned);
  138.     image->rowStart = (unsigned *)malloc(x);
  139.     image->rowSize = (int *)malloc(x);
  140.     if (image->rowStart == NULL || image->rowSize == NULL) {
  141.         fprintf(stderr, "Out of memory!\n");
  142.         exit(1);
  143.     }
  144.     image->rleEnd = 512 + (2 * x);
  145.     fseek(image->file, 512, SEEK_SET);
  146.     fread(image->rowStart, 1, x, image->file);
  147.     fread(image->rowSize, 1, x, image->file);
  148.     if (swapFlag) {
  149.         ConvertLong(image->rowStart, x/(int)sizeof(unsigned));
  150.         ConvertLong((unsigned *)image->rowSize, x/(int)sizeof(int));
  151.     }
  152.     }
  153.     return image;
  154. }
  155.  
  156. static void
  157. ImageClose(ImageRec *image) {
  158.     fclose(image->file);
  159.     free(image->tmp);
  160.     free(image->tmpR);
  161.     free(image->tmpG);
  162.     free(image->tmpB);
  163.     free(image);
  164. }
  165.  
  166. static void
  167. ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
  168.     unsigned char *iPtr, *oPtr, pixel;
  169.     int count;
  170.  
  171.     if ((image->type & 0xFF00) == 0x0100) {
  172.     fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
  173.     fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
  174.           image->file);
  175.  
  176.     iPtr = image->tmp;
  177.     oPtr = buf;
  178.     for (;;) {
  179.         pixel = *iPtr++;
  180.         count = (int)(pixel & 0x7F);
  181.         if (!count) {
  182.         return;
  183.         }
  184.         if (pixel & 0x80) {
  185.         while (count--) {
  186.             *oPtr++ = *iPtr++;
  187.         }
  188.         } else {
  189.         pixel = *iPtr++;
  190.         while (count--) {
  191.             *oPtr++ = pixel;
  192.         }
  193.         }
  194.     }
  195.     } else {
  196.     fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
  197.           SEEK_SET);
  198.     fread(buf, 1, image->xsize, image->file);
  199.     }
  200. }
  201.  
  202. unsigned *
  203. read_texture(char *name, int *width, int *height, int *components) {
  204.     unsigned *base, *lptr;
  205.     unsigned char *rbuf, *gbuf, *bbuf, *abuf;
  206.     ImageRec *image;
  207.     int y;
  208.  
  209.     image = ImageOpen(name);
  210.     
  211.     if(!image)
  212.     return NULL;
  213.     (*width)=image->xsize;
  214.     (*height)=image->ysize;
  215.     (*components)=image->zsize;
  216.     base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
  217.     rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  218.     gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  219.     bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  220.     abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  221.     if(!base || !rbuf || !gbuf || !bbuf)
  222.       return NULL;
  223.     lptr = base;
  224.     for(y=0; y<image->ysize; y++) {
  225.     if(image->zsize>=4) {
  226.         ImageGetRow(image,rbuf,y,0);
  227.         ImageGetRow(image,gbuf,y,1);
  228.         ImageGetRow(image,bbuf,y,2);
  229.         ImageGetRow(image,abuf,y,3);
  230.         rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
  231.         lptr += image->xsize;
  232.     } else if(image->zsize==3) {
  233.         ImageGetRow(image,rbuf,y,0);
  234.         ImageGetRow(image,gbuf,y,1);
  235.         ImageGetRow(image,bbuf,y,2);
  236.         rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
  237.         lptr += image->xsize;
  238.     } else if(image->zsize==2) {
  239.         ImageGetRow(image,rbuf,y,0);
  240.         ImageGetRow(image,abuf,y,1);
  241.         latorgba(rbuf,abuf,(unsigned char *)lptr,image->xsize);
  242.         lptr += image->xsize;
  243.     } else {
  244.         ImageGetRow(image,rbuf,y,0);
  245.         bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
  246.         lptr += image->xsize;
  247.     }
  248.     }
  249.     ImageClose(image);
  250.     free(rbuf);
  251.     free(gbuf);
  252.     free(bbuf);
  253.     free(abuf);
  254.  
  255.     return (unsigned *) base;
  256. }
  257.